# # 首先引入一个定义好的函数：
#
#
# def cal1():
#     """这是一个10+20求和的函数"""
#     add1, add2 = 10, 20
#     print(add1+add2)
#
#
# cal1()
# 可见这个函数不够灵活，只能计算10+20，想让其具有泛用性，应使用函数参数


def cal2(add2, add3):  # 括号内的变量现在是没有具体数值的，叫做形参，起到占位的作用
    """这是一个求和的函数"""
    print(add2+add3)


cal2(10, -1)  # 函数调用之时，括号内的实参会赋值给函数形参，注意：实参个数应与形参个数一致，否则报错
# 关于传参方式


def func(a, b, c):
    print(a, b, c)


func(1, 2, 3)  # 这是位置传参，也就是上面使用的方式
func(c=1, a=2, b=3)  # 这是关键字传参，注意同一个关键字不能赋值一样
func(1, c=5, b=3)  # 这是混合传参，注意关键字传参必须写在位置传参之后
# 关于缺省参数


def show_info(name, sex='保密'):  # 这里的sex就是缺省参数，缺省参数针对的是形参，同时存在缺省参数的话它要写在普通形参之后
    print(name, sex)


show_info('小明')  # 可见当函数形参使用了缺省值后，实参数目可以不与形参数目一致，但是要保证和非缺省形参个数一致，
# 若实参没有给缺省形参传递数值，则函数调用时对应形参会使用缺省值
show_info('小明', '男')  # 若实参给缺省形参传递了实参值，那么函数调用时对应形参使用的就是收到的实参值
# 关于不定长参数
# 有不定长位置（元组）参数和不定长关键字（字典）参数之分，针对的都是形参
# 不定长元组参数写法：*args，特点：该形参可以接收任意个数的位置传参数据
# 不定长字典参数写法：**kwargs，特点：该形参可以接收任意个数的关键字传参数据
# 一个函数完整的形参放置顺序：(普通形参, *args, 缺省形参, **kwargs)


def func1(*args, **kwargs):
    print(type(args), args)
    print(type(kwargs), kwargs)


func1()  # 注意接收任意个实参传递数据意味着可以不写实参
func1(1, 2, 3, 4, 5)
func1(a=1, b=3, c=5)
func1(1, 10, v=100)
# 若不定长传参使用的是列表，元组或是字典，应在传参的时候进行拆包
# 即在函数调用的时候，对容器拆包，如：func(*list, **dict)
